// 常量定义
const CONSTANTS = {
    WS_URL: 'ws://127.0.0.1:8080/idea',
    CMD_URL: 'ws://127.0.0.1:8080/cmd',
    ERROR_COLOR: '\x1b[31m',
    RESET_COLOR: '\x1b[0m'
}

// 输入状态
let isInputMode = !window.hasEditor
let inputBuffer = ''

// 页面元素引用
const statusIndicator = document.getElementById('status-indicator')
const runButton = document.getElementById('run')
const terminal = document.getElementById('terminal')

if (!window.hasEditor) {
    runButton.style.display = 'none'
    terminal.style.height = 'calc(100vh * 0.5)'
}

// UUID生成器
const generateUUID = () => {
    const arr = new Uint8Array(16)
    window.crypto.getRandomValues(arr)
    arr[6] = (arr[6] & 0x0f) | 0x40
    arr[8] = (arr[8] & 0x3f) | 0x80
    return Array.from(arr, byte => byte.toString(16).padStart(2, '0')).join('')
}

// 创建代码编辑器
const createEditor = () => {
    const editor = ace.edit('editor')
    editor.setTheme('ace/theme/monokai')
    editor.session.setMode("ace/mode/java")
    editor.setOptions({
        enableBasicAutocompletion: true,
        enableSnippets: true,
        enableLiveAutocompletion: true,
        fontSize: '18px',
        fontFamily: 'space mono',
        highlightActiveLine: true,
        highlightSelectedWord: true,
        showLineNumbers: true,
        tabSize: 4,
        showPrintMargin: false
    })
    return editor
}

// 创建终端
const createTerminal = () => {
    const terminal = new Terminal({
        theme: {
            foreground: '#F8F8F2',
            background: '#272822',
            cursor: '#F8F8F2'
        }
    })
    const fitAddon = new FitAddon.FitAddon()
    terminal.loadAddon(fitAddon)
    terminal.open(document.querySelector('#terminal'))
    fitAddon.fit()
    return terminal
}

// 处理终端输出
const handleTerminalOutput = (terminal, { type, body, newLine }) => {
    if (type === 'STDERR') {
        terminal.write(CONSTANTS.ERROR_COLOR);
    }
    terminal.write(`${body}${newLine ? '\r\n' : ''}`)
    if (type === 'STDERR') {
        terminal.write(CONSTANTS.RESET_COLOR)
    }
}

// 设置WebSocket连接
const setupWebSocket = (terminal, layer) => {
    const url = window.hasEditor ? CONSTANTS.WS_URL : CONSTANTS.CMD_URL
    const ws = new WebSocket(`${url}/${generateUUID()}`)

    ws.onopen = () => {
        statusIndicator.classList.add('connected')
        runButton.disabled = false
    }
    ws.onerror = error => {
        layer.msg(`错误: ${error.message}`)
        statusIndicator.classList.remove('connected')
    }
    ws.onmessage = e => {
        const message = JSON.parse(e.data)
        handleWebSocketMessage(message, terminal, layer)
    }

    return ws
}

// 处理WebSocket消息
const handleWebSocketMessage = (data, terminal, layer) => {
    switch (data.action) {
        case 'EXCEPTION':
            layer.msg(`${data.body}`)
            break
        case 'OUTPUT':
            handleTerminalOutput(terminal, data)
            break
        case 'WAIT':
            terminal.focus()
            runButton.style.display = 'none'
            isInputMode = true
            break
        case 'NOTIFY':
            isInputMode = false
            runButton.style.display = 'block'
            document.activeElement.blur()
            break
    }
}

layui.use('element', () => {
    if (window.hasEditor) {
        const editor = createEditor()
        layui.$('#run').click(() => {
            terminal.clear()
            const code = editor.getValue()
            ws.send(JSON.stringify({ action: 'RUN', body: code }))
        })
    }
    const terminal = createTerminal()
    const ws = setupWebSocket(terminal, layui.layer)
    terminal.onKey(key => {
        if (isInputMode) {
            handleKeyInput(key, terminal, ws)
        }
    })
})

const handleKeyInput = (key, terminal, ws) => {
    const char = key.domEvent.key
    if (char.length === 1) {
        inputBuffer += char
        terminal.write(char)
    } else {
        if (char === 'Enter') {
            const action = window.hasEditor ? 'INPUT' : 'PROCESS'
            ws.send(JSON.stringify({ action, body: inputBuffer }))
            terminal.write('\r\n');
            inputBuffer = ''
            return
        }
        if (char === 'Backspace' && inputBuffer.length > 0) {
            inputBuffer = inputBuffer.slice(0, -1)
            terminal.write('\b \b')
        }
    }
}